#include <stdio.h>

/**
 * 本例演示一些奇怪的数组索引
 * 
 * 因为C编译器不检查数组越界，所以连-1这种索引都是可以的
 * 主要看看汇编是咋实现的。
 * 
 * 这个代码在不同的机器上运行结果不一样。在c prime plus中，结果是：
value1 = 44, value2 = 88
-1 -1
0 1
1 3
2 5
3 7
4 9
5 1624678494
6 32767
value1 = 9, value2 = -1
address of arr[-1]: 0x7fff5fbff8cc
address of arr[4]: 0x7fff5fbff8e0
address of value1: 0x7fff5fbff8e0
address of value2: 0x7fff5fbff8cc
 * 可见，对arr数组的赋值，影响了变量value1和value2，而value1的地址和arr[4]的地址一样。
 * arr[-1]和value2的地址一样。
 * 在我的机器上运行结果是:
value1 = 44, value2 = 88
-1 -1
 0 1
 1 3
 2 5
 3 7
 4 9
 5 0
 6 783328768
value1 = 44, value2 = 88
address of arr[-1]: 0x7ffdb61ea65c
address of arr[4]: 0x7ffdb61ea670
address of value1: 0x7ffdb61ea654
address of value2: 0x7ffdb61ea658
 * 可见，他们的地址各不相同，不会互相影响。
 * 在我的这台机器上实际上看不出来效果，通过反编译可以发现，其实arr[-1]的地址是和i的地址相同，而value1和value2实际上是arr[-3]和arr[-4]不论如何原理是一样的。
*/

#define SIZE 4
int main(void)
{
    int value1 = 44;
    int arr[SIZE];
    int value2 = 88;
    int i;
    printf("value1 = %d, value2 = %d\n", value1, value2);
    for (i = -1; i <= SIZE; i++)
        arr[i] = 2 * i + 1;
    for (i = -1; i < 7; i++)
        printf("%2d %d\n", i, arr[i]);
    printf("value1 = %d, value2 = %d\n", value1, value2);
    printf("address of arr[-1]: %p\n", &arr[-1]);
    printf("address of arr[4]: %p\n", &arr[4]);
    printf("address of value1: %p\n", &value1);
    printf("address of value2: %p\n", &value2);
    return 0;
}